package com.cskaoyan.javase.network.util;

import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * UDP编程工具类
 * 通过v1版本代码，很容易就发现：
 *
 * 发送端构建传输数据的数据包时，基本的代码形式是一致的。
 * 接收端接收传输的数据包时，基本的代码形式也是一致的。
 * 接收端解析接收到的消息时，基本的代码形式也是一致的。
 * 既然由重复代码，那当然要偷个懒，提取出工具类，实现代码复用。
 *
 * @since 11:20
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class UDPNetworkUtils {
    private UDPNetworkUtils() {
    }

    // 1.发送端构建发送的消息的数据报包

    /**
     * 发送端构建发送的消息的数据报包
     *
     * @param msg 发送端发送的消息
     * @param targetIP 目的IP地址
     * @param port 目的端口号
     * @return java.net.DatagramPacket
     * @author wuguidong@cskaoyan.onaliyun.com
     * @since 11:24
     */
    public static DatagramPacket getSendPacket(String msg, String targetIP, int port) throws UnknownHostException {
        // // 构造数据报包，用来将长度为length偏移量为offset的包发送到指定主机上的指定端口号。
        // DatagramPacket(byte[] buf,  int offset, int length, InetAddress address, int port)
        // // 构造数据报包，用来将长度为length的包发送到指定主机上的指定端口号。
        // DatagramPacket(byte[] buf, int length, InetAddress address, int port)
        // 1.String msg --> byte数组
        byte[] msgBytes = msg.getBytes();
        // 2.String targetIP --> InetAddress
        // 3.new对象返回
        return new DatagramPacket(msgBytes, msgBytes.length, InetAddress.getByName(targetIP), port);
    }

    // 2.接收端接收数据报包时,封装空的数据报包
    public static DatagramPacket getReceiverPacket() {
        // // 构造 DatagramPacket，用来接收长度为length的包，在缓冲区中指定了偏移量。
        // DatagramPacket(byte[] buf, int offset, int length)
        // // 构造 DatagramPacket，用来接收长度为length的数据包。
        // DatagramPacket(byte[] buf, int length)
        // 直接new对象返回即可
        return new DatagramPacket(new byte[1024], 1024);
    }

    // 3.接收端解析数据报包,获取发送端的消息
    public static String parsePacket(DatagramPacket send) {
        // // 返回数据缓冲区，即数据包封装的字节数据
        // byte[] getData()
        // // 返回将要发送或接收到的数据的长度。
        // int getLength()
        // // 返回将要发送或接收到的数据的偏移量。
        // int getOffset()
        // // 获取数据包（要发送到的或者发送者）的IP地址
        // // 获取数据包（要发送到的或者发送者）的IP地址和端口号
        // SocketAddress getSocketAddress()

        // 1.获取byte数组
        byte[] data = send.getData();
        // 2.获取偏移量和发送的数据长度
        int length = send.getLength();
        int offset = send.getOffset();
        // 3.new String
        String msg = new String(data, offset, length);
        // 4.获取发送端的IP地址和端口号
        // 5.拼接字符串,返回这个字符串
        return "发送者是" + send.getSocketAddress() + ",他发来的消息是: " + msg;
    }
}
